package roborally.util;

import java.util.*;
import roborally.Board;
import roborally.Pieces.*;
/**
 * This is a class representing an Iterator over a Board using a List. 
 * Each subclass has to overwrite the method satisfiesCondition, which can be done by
 * using this class as a superclass for an anonymous inner class inside a method call.
 * 
 * @version 3.0
 * @author 	Bart Opsomer 2de Bachelor Ingenieurswetenschappen Electrotechniek-Computerwetenschappen 
 * 		   	Peter Opsomer 1ste Master Wiskundige IngenieursTechnieken
 */
public abstract class BoardIterator implements Iterator<GamePiece> {
	// the list in which the items that satisfy the condition, are stored
	private List<GamePiece> list;
	/**
	 * Initialize the list, with an empty List<GamePiece>
	 */
	public BoardIterator() {
		list = new ArrayList<GamePiece>();
	}
	/**
	 * Fill the list with gamePieces that satisfy the given condition
	 * @param board the board on which the iterator works
	 * @post	all pieces in the list satisfy the given condition
	 * 			| foreach piece in new.list
	 * 			|	satisfiesCondition(piece)
	 */
	public void initiate(Board board) 
	{
		for(Item item : board.getAllItems() ) {
			if(satisfiesCondition(item) ) {
				list.add(item);
			}
		}
		for(Robot robot : board.getRobots() ) {
			if(satisfiesCondition(robot) ) {
				list.add(robot);
			}
		}
		for(Wall wall : board.getWalls() ) {
			if(satisfiesCondition(wall) ) {
				list.add(wall);
			}
		}
	}
	/**
	 * returns whether the iterator has items to iterate over
	 * @return	result = !list.isEmpty()
	 */
	@Override
	public boolean hasNext() {
		return !list.isEmpty();
	}
	
	/**
	 * returns the next item that satisfies the given condition
	 */
	@Override
	public GamePiece next() {
		GamePiece toReturn =  list.get(0);
		list.remove(toReturn);
		return toReturn;
	}
	/**
	 * Not a supported operation, the users of this class has to remove the piece himself
	 */
	@Override
	public void remove() {
		throw new UnsupportedOperationException();
	}
	/**
	 * returns if  the condition is satisfied by the given piece
	 * @param piece the piece to be checked if it satisfies the condition, implemented by the user of this class
	 */
	public abstract boolean satisfiesCondition(GamePiece piece);
}
